﻿/* 2. Write a program that reads a rectangular matrix of size N x M 
 * and finds in it the square 3 x 3 that has maximal sum of its elements. */

using System;

public class SquareWithMaxSum
{
    public static int n;
    public static int m;
    public static double[,] matrix;
    public static int x;
    public static int y;

    public static int maxSymbols;

    public static int resultX;
    public static int resultY;
    public static int results = 1;

    public static void Main()
    {
        DataInput();
        PrintResults(CheckAllSquares());
    }

    public static void DataInput()
    {
        int symbols = 0;

        do
        {
            Console.Clear();
            Console.Write("\nRows of matrix: ");
            if (int.TryParse(Console.ReadLine(), out n) && (0 < n))
            {
                do
                {
                    Console.Clear();
                    Console.Write("\nRows of matrix: {0}\nColumns of matrix: ", n);
                    if (int.TryParse(Console.ReadLine(), out m) && (0 < m))
                    {
                        matrix = new double[n, m];

                        for (int i = 0; i < n; i++)
                        {
                            for (int j = 0; j < m; j++)
                            {
                                do
                                {
                                    Console.Clear();
                                    Console.Write("\nRows of matrix: {0}\nColumns of matrix: {1}\n\n", n, m);
                                    for (int k = 0; k < i * m + j; k++)
                                    {
                                        Console.WriteLine("matrix[{0}, {1}] = {2}", k / m, k % m, matrix[k / m, k % m]);
                                        if ((k + 1) % m == 0)
                                            Console.WriteLine();
                                    }

                                    Console.Write("matrix[{0}, {1}] = ", i, j);
                                    if ((double.TryParse(Console.ReadLine(), out matrix[i, j])))
                                    {
                                        symbols = matrix[i, j].ToString().Length;
                                        if (maxSymbols < symbols)
                                            maxSymbols = symbols;

                                        break;
                                    }
                                } while (true);
                            }

                            Console.WriteLine();
                        }

                        break;
                    }
                } while(true);

                break;
            }
        } while (true);

        Console.WriteLine();

        do
        {
            Console.Clear();
            Console.Write("\nRows of matrix: {0}\nColumns of matrix: {1}\n\n", n, m);
            PrintMatrix(0, 0, n, m);

            Console.Write("Rows of square: ");
            if (int.TryParse(Console.ReadLine(), out x) && (0 < x) && (x <= n))
            {
                do
                {
                    Console.Clear();
                    Console.Write("\nRows of matrix: {0}\nColumns of matrix: {1}\n\n", n, m);
                    PrintMatrix(0, 0, n, m);

                    Console.Write("Rows of square: {0}\nColumns of square: ", x);
                    if (int.TryParse(Console.ReadLine(), out y) && (0 < y) && (y <= m))
                        break;
                } while (true);

                break;
            }
        } while (true);

        Console.WriteLine();
    }

    public static void PrintMatrix(int startX, int startY, int endX, int endY)
    {
        for (int i = 0; i < endX; i++)
        {
            Console.Write("{0}{1}", new string(' ', (1 + maxSymbols - matrix[startX + i, startY].ToString().Length)),
                matrix[startX + i, startY]);
            for (int j = 1; j < endY; j++)
                Console.Write("{0}{1}", new string(' ', (2 + maxSymbols - matrix[startX + i, startY + j].ToString().Length)),
                    matrix[startX + i, startY + j]);

            Console.WriteLine();
        }

        Console.WriteLine();
    }

    public static double? CheckAllSquares()
    {
        double? maxSum = null;
        double? currentSum = null;

        for (int i = 0; i <= n - x; i++)
        {
            for (int j = 0; j <= m - y; j++)
            {
                currentSum = CheckSquare(i, j);

                if ((maxSum == null) || (maxSum < currentSum))
                {
                    maxSum = currentSum;
                    resultX = i;
                    resultY = j;
                    results = 1;
                }
                else if (maxSum == currentSum)
                    results++;
            }
        }

        return maxSum;
    }

    public static double CheckSquare(int i, int j)
    {
        double sum = 0;

        for (int p = i; p < i + x; p++)
            for (int q = j; q < j + y; q++)
                sum += matrix[p, q];

        return sum;
    }

    public static void PrintResults(double? sum)
    {
        if (results == 1)
            Console.WriteLine("The unique square with maximal sum ({0}) is", sum);
        else
            Console.WriteLine("One of all {0} squares with maximal sum ({1}) is", results, sum);

        PrintMatrix(resultX, resultY, x, y);
    }
}